package com.nulldev.util.VariableAPI.util.strings.codepoint;

public interface Internal {
	public static final int MAX_CODE_POINT = 0X10FFFF;
	static final int CHAR_ERROR = 0xFFFFFFFF;
	static final byte LATIN1 = 0;
	static final byte UTF16 = 1;

	/*
	 * StringIndexOutOfBoundsException if {@code index} is negative or greater than
	 * or equal to {@code length}.
	 */
	static void checkIndex(int index, int length) {
		if (index < 0 || index >= length) {
			throw new StringIndexOutOfBoundsException("index " + index + ",length " + length);
		}
	}

	/*
	 * StringIndexOutOfBoundsException if {@code offset} is negative or greater than
	 * {@code length}.
	 */
	static void checkOffset(int offset, int length) {
		if (offset < 0 || offset > length) {
			throw new StringIndexOutOfBoundsException("offset " + offset + ",length " + length);
		}
	}

	/*
	 * Check {@code offset}, {@code count} against {@code 0} and {@code length}
	 * bounds.
	 *
	 * @throws StringIndexOutOfBoundsException If {@code offset} is negative, {@code
	 * count} is negative, or {@code offset} is greater than {@code length - count}
	 */
	static void checkBoundsOffCount(int offset, int count, int length) {
		if (offset < 0 || count < 0 || offset > length - count) {
			throw new StringIndexOutOfBoundsException("offset " + offset + ", count " + count + ", length " + length);
		}
	}

	/*
	 * Check {@code begin}, {@code end} against {@code 0} and {@code length} bounds.
	 *
	 * @throws StringIndexOutOfBoundsException If {@code begin} is negative, {@code
	 * begin} is greater than {@code end}, or {@code end} is greater than {@code
	 * length}.
	 */
	static void checkBoundsBeginEnd(int begin, int end, int length) {
		if (begin < 0 || begin > end || end > length) {
			throw new StringIndexOutOfBoundsException("begin " + begin + ", end " + end + ", length " + length);
		}
	}

	public static boolean isBmpCodePoint(int codePoint) {
		return codePoint >>> 16 == 0;
	}

	static char[] toUpperCaseCharArray(int codePoint) {
		// As of Unicode 6.0, 1:M uppercasings only happen in the BMP.
		assert isBmpCodePoint(codePoint);
		return CharacterData.of(codePoint).toUpperCaseCharArray(codePoint);
	}

	static int toUpperCaseEx(int codePoint) {
		assert isValidCodePoint(codePoint);
		return CharacterData.of(codePoint).toUpperCaseEx(codePoint);
	}

	public static boolean isValidCodePoint(int codePoint) {
		int plane = codePoint >>> 16;
		return plane < ((MAX_CODE_POINT + 1) >>> 16);
	}

	final static char[] DigitTens =
		{ '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2',
				'3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '5', '5', '5', '5', '5', '5', '5', '5', '5',
				'5', '6', '6', '6', '6', '6', '6', '6', '6', '6', '6', '7', '7', '7', '7', '7', '7', '7', '7', '7', '7', '8', '8', '8', '8', '8', '8', '8', '8',
				'8', '8', '9', '9', '9', '9', '9', '9', '9', '9', '9', '9', };

	final static char[] DigitOnes =
		{ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
				'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8',
				'9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7',
				'8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', };

	// I use the "invariant division by multiplication" trick to
	// accelerate Integer.toString. In particular we want to
	// avoid division by 10.
	//
	// The "trick" has roughly the same performance characteristics
	// as the "classic" Integer.toString code on a non-JIT VM.
	// The trick avoids .rem and .div calls but has a longer code
	// path and is thus dominated by dispatch overhead. In the
	// JIT case the dispatch overhead doesn't exist and the
	// "trick" is considerably faster than the classic code.
	//
	// TODO-FIXME: convert (x * 52429) into the equiv shift-add
	// sequence.
	//
	// RE: Division by Invariant Integers using Multiplication
	// T Gralund, P Montgomery
	// ACM PLDI 1994
	//
}
